﻿using System;
using System.Web.Mvc;
using System.Reflection;
using IValidate;
using Html;

public static class HtmlHelperExtensions
{
	/// <summary>
	/// Renders an input element containing attributes that indicate how
	/// it should be validated.
	/// </summary>
	/// <param name="htmlHelper">The HTML helper.</param>
	/// <param name="name">The name of the property on the model we are binding.</param>
	/// <returns>HTML input element ready to be validated on the client side.</returns>
	public static string ValidateTextBox(this HtmlHelper htmlHelper, string name)
	{
		Element input = new Element("input", "type=text")
			.AddAttributeFormat("id", name)
			.AddAttributeFormat("name", name)
			.AddCssClasses("validate");

		object model = htmlHelper.ViewDataContainer.ViewData.Model;//passed into the view from the controller
		PropertyInfo prop = model.GetType().GetProperty(name);

		//find all of the attributes that implement IModelValidator
		object[] attribs = prop.GetCustomAttributes(typeof(IModelValidator), true);
		if (attribs != null && attribs.Length > 0)
		{
			IModelValidator[] validators =
				Array.ConvertAll<object, IModelValidator>(attribs,
				obj =>
				{
					return obj as IModelValidator;
				});
			foreach (IModelValidator validator in validators)
			{
				AddValidation((validator as ValidateRequiredAttribute), input);
				AddValidation((validator as ValidateMaxLengthAttribute), input);
				AddValidation((validator as ValidateMinLengthAttribute), input);
				AddValidation((validator as ValidateLengthAttribute), input);
				AddValidation((validator as ValidateEmailAttribute), input);
				AddValidation((validator as ValidateDateAttribute), input);
				input.AddAttribute("message", validator.ErrorMessage);
				if (validator.Required) input.AddCssClasses("required");
			}
		}
		object value = prop.GetValue(model, null) ?? "";
		if (prop.PropertyType == typeof(DateTime))
		{
			DateTime date = DateTime.TryParse(value.ToString(), out date) ? date : DateTime.MinValue;
			if (date == DateTime.MinValue)
				value = "";
		}
		return input.AddAttributeFormat("value", "{0}", value.ToString());
	}

	private static void AddValidation(ValidateDateAttribute validator, Element element)
	{
		if (validator == null) return;
		element.AddCssClasses("date");
	}

    private static void AddValidation(ValidateEmailAttribute validator, Element element)
	{
		if (validator == null) return;
		element.AddCssClasses("email");
	}
    private static void AddValidation(ValidateLengthAttribute validator, Element element)
	{
		if (validator == null) return;
		element.AddAttribute("minlength", validator.MinLength);
		element.AddAttribute("maxlength", validator.MaxLength);
	}
	
	private static void AddValidation(ValidateRequiredAttribute validator, Element element)
	{
		if (validator == null) return;
		element.AddCssClasses("required");
	}
	private static void AddValidation(ValidateMaxLengthAttribute validator, Element element)
	{
		if (validator == null) return;
		element.AddAttribute("maxlength", validator.MaxLength);
		
	}
	private static void AddValidation(ValidateMinLengthAttribute validator, Element element)
	{
		if (validator == null) return;
		element.AddAttribute("minlength", validator.MinLength);
		
	}
}
